/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package controle.gui.frames.internos;

import controle.gui.frames.ControleFramePrincipal;
import controle.gui.frames.internos.superclasses.ControleBoletins;
import controle.gui.utils.ApagaElementosDaInterface;
import controle.gui.utils.EnabledGUIElements;
import controle.gui.utils.setEnabledGUIElements;
import controle.interfaces.Constantes;
import controle.utils.Datas;
import controle.utils.Horas;
import controle.utils.ReportUtils;
import gui.componentes.RendererTable;
import gui.frames.FramePrincipal;
import gui.frames.internos.IFBoletimTratamento;
import gui.frames.internos.IFVisitaTratamento;
import java.io.InputStream;
import java.sql.Date;
import java.sql.Time;
import java.text.ParseException;
import java.util.*;
import javax.swing.JOptionPane;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import modelo.*;
import persistencia.dao.AbstractDAO;
import persistencia.dao.TransacaoDAO;
import persistencia.session.ConnectionFactory;

/**
 *
 * @author Maycon Fernando Silva Brito
 * @author mayconfsbrito@gmail.com
 */
public class ControleBoletimTratamento extends ControleBoletins {

    /*
     * Variáveis da classe
     */
    public IFBoletimTratamento frame = null;
    public TreeSet<Visitatratamento> setVisitas = new TreeSet<Visitatratamento>();
    private ArrayList<Integer> listVisitasRemovidas = new ArrayList<Integer>();

    //Construtor da classe
    public ControleBoletimTratamento(IFBoletimTratamento frame) {
        super(frame);
        this.frame = frame;
    }

    //Inicializa o frame
    public void inicializa() {

        //Torna o frame visível
        frame.setVisible(true);

        this.limparGUI();

        //Inicializa eventos da tabela
        frame.tabela.getSelectionModel().addListSelectionListener(frame.listener);
        frame.tabela.getColumnModel().getSelectionModel().addListSelectionListener(frame.listener);

    }

    /**
     * Especificações em @InternalFrame
     */
    public void guiAtiva(boolean estado) {
        if (estado) {
            setEnabledGUIElements.enabledJComponent(frame.buttonCadastro);
            setEnabledGUIElements.disabledJComponent(frame.buttonAlterar, frame.buttonDesativar, frame.buttonAtivar, frame.buttonImprimir);

        } else {
            setEnabledGUIElements.enabledJComponent(frame.buttonAlterar, frame.buttonDesativar, frame.buttonAtivar, frame.buttonImprimir);
            setEnabledGUIElements.disabledJComponent(frame.buttonCadastro);
        }
    }

    /**
     * Configura o comportmento da interface de acordo se o boletim está ativado
     * ou desativado
     */
    public void guiAtivacaoBoletim(Boletimtratamento boletim) {

        if (boletim.isAtivo()) {
            EnabledGUIElements.enabledJComponent(frame.buttonDesativar, frame.buttonAlterar, frame.buttonInserir, frame.buttonRemover, frame.textData,
                    frame.textCodigoGRS, frame.textCodigoMunicipio, frame.textCodigoLocalidade, frame.comboLocalidade, frame.comboAgente, frame.textCodigoAgente,
                    frame.textSemana, frame.textNumeroAtividade, frame.radioAtvTF, frame.radioAtvDF, frame.radioAtvPE, frame.radioAtvPVE, frame.radioCategoriaOutros,
                    frame.radioCategoriaSede, frame.buttonImprimir, frame.textSemanaAno, frame.textNumeroAtividadeAno);
            frame.buttonAtivar.setEnabled(false);

        } else {
            EnabledGUIElements.disabledJComponent(frame.buttonDesativar, frame.buttonAlterar, frame.buttonInserir, frame.buttonRemover, frame.textData, frame.comboCordRegional,
                    frame.textCodigoGRS, frame.textCodigoMunicipio, frame.textCodigoLocalidade, frame.comboLocalidade, frame.comboAgente, frame.textCodigoAgente,
                    frame.textSemana, frame.textNumeroAtividade, frame.radioAtvTF, frame.radioAtvDF, frame.radioAtvPE, frame.radioAtvPVE, frame.radioCategoriaOutros,
                    frame.radioCategoriaSede, frame.buttonImprimir, frame.textSemanaAno, frame.textNumeroAtividadeAno);
            frame.buttonAtivar.setEnabled(true);

        }

    }

    /**
     * Verifica o acesso do usuário para utilizar o frame
     */
    protected void verificaAcessos() {

        //Verifica a permissao de @user para este frame
        if (!ControleFramePrincipal.acessos.get(Constantes.PERMISSAO_CADASTRA_ALTERA_BOLETIM_TRATAMENTO).isAcesso()) {
            EnabledGUIElements.disabledJComponent(frame.buttonCadastro, frame.buttonAlterar, frame.buttonDesativar);
        }
    }

    /**
     * Limpa os componentes do frame
     */
    public void limparGUI() {

        frame.tabela.clearSelection();
        frame.tabelaVisitas.clearSelection();
        this.inicializaModelTabelaVisitas().setNumRows(0);
        new ApagaElementosDaInterface().apagaJTextField(frame.textData, frame.textCodigoGRS, frame.textId, frame.textSemanaAno, frame.textNumeroAtividadeAno,
                frame.textCodigoAgente, frame.textCodigoLocalidade, frame.textNumeroAtividade, frame.textSemana, frame.textTurma, frame.textCodigoMunicipio, frame.textNomeMunicipio);
        new ApagaElementosDaInterface().apagaJComboBox(frame.comboAgente, frame.comboLocalidade, frame.comboCordRegional, frame.comboCordRegional);
        EnabledGUIElements.disabledJComponent(frame.textCodigoLocalidade, frame.comboLocalidade);
        frame.radioAtvTF.setSelected(true);

        //Limpa a memória do frame
        this.setVisitas = new TreeSet<Visitatratamento>();
        this.listVisitasRemovidas = new ArrayList<Integer>();

        //Configura o comportamento da gui de acordo com as permissões do usuário
        this.guiAtiva(true);
        this.verificaAcessos();
    }

    /**
     * Preenche todos os componentes da GUI a partir do objeto selecionado na
     * tabela
     */
    public void tabelaPreencheGUI() {

        int linha = frame.tabela.getSelectedRow();
        Integer cod;
        try {
            cod = (Integer) frame.tabela.getValueAt(linha, 0);
        } catch (IndexOutOfBoundsException er) {
            cod = 0;
            return;
        }

        List<Boletimtratamento> consulta = AbstractDAO.consultar(
                "from Boletimtratamento b left join fetch b.visitatratamentos v left join fetch b.agente a inner join fetch b.localidade l "
                + "inner join fetch b.municipio m left join fetch v.quadra left join fetch v.logradouro left join fetch v.imovel"
                + " where b.idBoletimTratamento=" + cod + " ORDER BY v.idVisitaTratamento");

        if (consulta.size() > 0) {
            Boletimtratamento boletim = consulta.get(0);
            this.preencheGui(boletim);
        }
    }

    /**
     * Preenche a gui de acordo com o objeto
     *
     * @param boletim
     * @return
     */
    public boolean preencheGui(Boletimtratamento boletim) {

        frame.textId.setText(Integer.toString(boletim.getIdBoletimTratamento()));
        frame.textData.setText(Datas.getText(boletim.getData(), "dd/MM/yyyy"));
        frame.comboCordRegional.setSelectedItem(boletim.getCoordenadorRegional());
        frame.textCodigoGRS.setText(boletim.getGrs());
        frame.textCodigoAgente.setText(boletim.getAgente().getIdAgente() + "");
        frame.textCodigoLocalidade.setText(boletim.getLocalidade().getCodigo().toString());
        frame.comboAgente.setSelectedItem(boletim.getAgente().getNome());
        frame.textTurma.setText(boletim.getTurma());
        frame.textCodigoMunicipio.setText(boletim.getMunicipio().getCodigo());
        frame.textNomeMunicipio.setText(boletim.getMunicipio().getNome());
        frame.comboLocalidade.setSelectedItem(boletim.getLocalidade().getNome());

        StringTokenizer tok1 = new StringTokenizer(boletim.getNumeroAtividade(), "/");
        frame.textNumeroAtividade.setText(tok1.nextToken());
        frame.textNumeroAtividadeAno.setText(tok1.nextToken("").replaceAll("/", ""));

        StringTokenizer tok2 = new StringTokenizer(boletim.getSemanaEpid(), "/");
        frame.textSemana.setText(tok2.nextToken());
        frame.textSemanaAno.setText(tok2.nextToken("").replaceAll("/", ""));

        //Verifica a categoria
        if (boletim.getCategoria().equals(Constantes.SEDE)) {
            frame.radioCategoriaSede.setSelected(true);
        } else {
            frame.radioCategoriaOutros.setSelected(true);
        }

        //Verifica a atividade
        if (boletim.getTipoAtividade().equals(Constantes.DF)) {
            frame.radioAtvDF.setSelected(true);
        } else if (boletim.getTipoAtividade().equals(Constantes.PE)) {
            frame.radioAtvPE.setSelected(true);
        } else if (boletim.getTipoAtividade().equals(Constantes.PVE)) {
            frame.radioAtvPVE.setSelected(true);
        } else {
            frame.radioAtvTF.setSelected(true);
        }

        //Preenche as visitas do boletim atual
        this.setVisitas.clear();
        for (Iterator it = boletim.getVisitatratamentos().iterator(); it.hasNext();) {
            this.setVisitas.add((Visitatratamento) it.next());
        }
        this.listVisitasRemovidas = new ArrayList<Integer>();
        this.setTabelaVisitas();

        //Configura o comportamento dos botões da interface
        new EnabledGUIElements().enabledJComponent(frame.buttonInserir, frame.buttonRemover);
        frame.buttonCadastro.setEnabled(false);
        EnabledGUIElements.enabledJComponent(frame.buttonAlterar, frame.buttonDesativar);
        this.guiAtiva(false);
        this.guiAtivacaoBoletim(boletim);
        this.verificaAcessos();

        return true;
    }

    /**
     * Preenche a tabela de visitas de acordo com o Boletim Selecionado na
     * tabela principal
     */
    public void setTabelaVisitas() {

        DefaultTableModel modelo = this.inicializaModelTabelaVisitas();
        modelo.setNumRows(0);

        //Verifica se há alguma visista para este boletim
        if (this.setVisitas != null) {
            if (this.setVisitas.size() > 0) {
                
                Collections.sort(listVisitasRemovidas);

                //Percorre cada visita e preenche cada linha da tabela de visitas
                for (Iterator it = this.setVisitas.iterator(); it.hasNext();) {

                    Visitatratamento obj = (Visitatratamento) it.next();
                    String pendencia = "";

                    if (!obj.getPendenciaFech() && !obj.getPendenciaRec() && !obj.getPendenciaResg()) {
                        pendencia = "Nenhuma";

                    } else {
                        pendencia = obj.getPendenciaFech() ? "Fechada" : pendencia;
                        pendencia = obj.getPendenciaRec() ? "Recusada" : pendencia;
                        pendencia = obj.getPendenciaResg() ? "Resgatada" : pendencia;

                    }
                    modelo.addRow(new Object[]{obj.getIdVisitaTratamento(), obj.getHora(), obj.getQuadra().getCodigo(),
                                obj.getLogradouro().getNome(), obj.getImovel().getNumero(), obj.getImovel().getComplemento(), pendencia, 
                                obj.isQuadraConcluida() ? "Sim" : "", obj.isUltimaVisitaBoletim() ? "Sim" : ""});
                }
            }
        }
    }

    /**
     * Seta e captura o modelo da tabela de visitas
     */
    public DefaultTableModel inicializaModelTabelaVisitas() {

        TableColumn coluna0 = frame.tabelaVisitas.getColumnModel().getColumn(0);
        TableColumn coluna1 = frame.tabelaVisitas.getColumnModel().getColumn(1);
        TableColumn coluna2 = frame.tabelaVisitas.getColumnModel().getColumn(2);
        TableColumn coluna3 = frame.tabelaVisitas.getColumnModel().getColumn(3);
        TableColumn coluna4 = frame.tabelaVisitas.getColumnModel().getColumn(4);
        TableColumn coluna5 = frame.tabelaVisitas.getColumnModel().getColumn(5);
        TableColumn coluna6 = frame.tabelaVisitas.getColumnModel().getColumn(6);
        TableColumn coluna7 = frame.tabelaVisitas.getColumnModel().getColumn(7);
        TableColumn coluna8 = frame.tabelaVisitas.getColumnModel().getColumn(8);

        //Dimensiona as colunas na tabela
        coluna0.setPreferredWidth(40);
        coluna1.setPreferredWidth(80);
        coluna2.setPreferredWidth(40);
        coluna3.setPreferredWidth(180);
        coluna4.setPreferredWidth(60);
        coluna5.setPreferredWidth(60);
        coluna6.setPreferredWidth(60);
        coluna7.setPreferredWidth(30);
        coluna8.setPreferredWidth(30);

        //Aplica o modelo
        final DefaultTableModel modelo = (DefaultTableModel) frame.tabelaVisitas.getModel();
        modelo.setNumRows(0);

        //Configura eventos do modelo da tabela de produtos
        modelo.addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
            }
        });

        return modelo;
    }

    /**
     * Especificações do método em @InternalFrame
     */
    protected void listarTodosElementosNaTabela() {

        List<Boletimtratamento> list = AbstractDAO.listar("Boletimtratamento");
        listarPesquisaNaTabela(list);
    }

    /**
     * Especificações do método em @InternalFrame
     */
    private void listarPesquisaNaTabela(List<Boletimtratamento> list) {

        frame.tabela.getColumnModel().getColumn(0).setMinWidth(20);
        frame.tabela.getColumnModel().getColumn(1).setMinWidth(80);
        frame.tabela.getColumnModel().getColumn(2).setMinWidth(180);
        frame.tabela.getColumnModel().getColumn(3).setMinWidth(240);
        frame.tabela.getColumnModel().getColumn(4).setMinWidth(160);

        DefaultTableModel modelo = (DefaultTableModel) frame.tabela.getModel();
        modelo.setNumRows(0);
        limparGUI();

        //Inicializa o DefaultTableCellRender modificado para personalizar algumas células
        DefaultTableCellRenderer renderer = new RendererTable(list);

        if (list != null) {
            try {
                for (int i = 0; i < list.size(); i++) {
                    Boletimtratamento boletim = list.get(i);
                    modelo.addRow(new Object[]{boletim.getIdBoletimTratamento(), Datas.toString(boletim.getData()), boletim.getMunicipio().getNome(),
                                boletim.getLocalidade().getNome(), boletim.getAgente().getNome()});

                    //Altera as propriedades das células desta linha de acordo com o estado de conclusão da transação atual*
                    frame.tabela.getColumnModel().getColumn(0).setCellRenderer(renderer);
                    frame.tabela.getColumnModel().getColumn(1).setCellRenderer(renderer);
                    frame.tabela.getColumnModel().getColumn(2).setCellRenderer(renderer);
                    frame.tabela.getColumnModel().getColumn(3).setCellRenderer(renderer);
                    frame.tabela.getColumnModel().getColumn(4).setCellRenderer(renderer);
                }

            } catch (Exception er) {
                JOptionPane.showMessageDialog(frame, "Erro ao listar os objetos na tabela!\n\n" + er, "Erro na listagem!", JOptionPane.ERROR_MESSAGE);
                er.printStackTrace();
            }
        }

    }

    /**
     * Instancia o logradouro a partir dos elementos da interface gráfica
     *
     * @return null caso haja algum erro ou o objeto Boletimtratamento caso
     * esteja tudo certo
     */
    public Boletimtratamento criaBoletim(int opcao) {

        //Caso o usuário confirme o evento
        if (opcao == JOptionPane.YES_OPTION) {

            //Verifica se todos os campos estão preenchidos
            if (!frame.textData.getText().isEmpty()) {
                if (!frame.textCodigoGRS.getText().isEmpty()) {
                    if (frame.comboCordRegional.getSelectedIndex() > 0) {
                        if (!frame.textCodigoMunicipio.getText().isEmpty()) {
                            if (!frame.textCodigoLocalidade.getText().isEmpty()) {
                                if (frame.comboAgente.getSelectedIndex() != 0) {
                                    if (!frame.textNumeroAtividade.getText().isEmpty() && !frame.textNumeroAtividadeAno.getText().isEmpty()) {
                                        if (!frame.textSemana.getText().isEmpty() && !frame.textSemanaAno.getText().isEmpty()) {

                                            //Verifica se o número da semana de Número Atividade ou Semana Epid. é maior do que 53
                                            if (Integer.parseInt(frame.textNumeroAtividade.getText()) > 53
                                                    || Integer.parseInt(frame.textSemana.getText()) > 53) {
                                                JOptionPane.showMessageDialog(frame, "A número da semana em \"Sem. Epid.\" ou \"nº Atividade\" não pode ser maior do que 53.",
                                                        "Atenção!", JOptionPane.WARNING_MESSAGE);
                                                return null;
                                            }

                                            //Instancia variáveis
                                            Date data = Datas.getDate(frame.textData.getText());
                                            data = Datas.verificaDigitosAno(data);
                                            String coordenador = frame.comboCordRegional.getSelectedItem().toString();
                                            Municipio municipio = (Municipio) AbstractDAO.consultar("Municipio", "codigo='" + frame.textCodigoMunicipio.getText() + "'").get(0);
                                            Localidade localidade = (Localidade) AbstractDAO.consultar("Localidade", "codigo='" + frame.textCodigoLocalidade.getText()
                                                    + "' AND idMunicipio=" + municipio.getIdMunicipio()).get(0);
                                            Agente agente = (Agente) AbstractDAO.consultar("Agente", "codigo='" + frame.textCodigoAgente.getText() + "'").get(0);
                                            String categoria = null;
                                            String turma = frame.textTurma.getText();
                                            String numeroAtividade = frame.textNumeroAtividade.getText() + "/" + frame.textNumeroAtividadeAno.getText();
                                            String semana = frame.textSemana.getText() + "/" + frame.textSemanaAno.getText();
                                            String tratamentoAtividade = null;
                                            String grs = frame.textCodigoGRS.getText();

                                            //Categoria
                                            if (frame.radioCategoriaSede.isSelected()) {
                                                categoria = Constantes.SEDE;
                                            } else {
                                                categoria = Constantes.OUTROS;
                                            }

                                            //Atividade
                                            if (frame.radioAtvDF.isSelected()) {
                                                tratamentoAtividade = Constantes.DF;
                                            } else if (frame.radioAtvPE.isSelected()) {
                                                tratamentoAtividade = Constantes.PE;
                                            } else if (frame.radioAtvPVE.isSelected()) {
                                                tratamentoAtividade = Constantes.PVE;
                                            } else {
                                                tratamentoAtividade = Constantes.TF;
                                            }

                                            Boletimtratamento boletim = new Boletimtratamento(agente, localidade, municipio, coordenador, grs, categoria, turma,
                                                    data, semana, numeroAtividade, tratamentoAtividade, true);

                                            //Verifica o id
                                            if (!frame.textId.getText().trim().isEmpty()) {
                                                boletim.setIdBoletimTratamento(Integer.parseInt(frame.textId.getText().trim()));
                                            }

                                            //Armazena as visitas da memória do frame no boletim atual
                                            for (Iterator it = this.setVisitas.iterator(); it.hasNext();) {
                                                ((Visitatratamento) it.next()).setBoletimtratamento(boletim);
                                            }
                                            boletim.setVisitatratamentos(this.setVisitas);

                                            //Retorna o objeto
                                            return boletim;

                                        } else {
                                            JOptionPane.showMessageDialog(frame, "Atenção! A semana epidemiológica deve ser preenchida.", "Semana epidemiológica não preenchida!", JOptionPane.WARNING_MESSAGE);
                                        }
                                    } else {
                                        JOptionPane.showMessageDialog(frame, "Atenção! O número da atividade deve ser preenchida.", "Número da atividade não preenchida!", JOptionPane.WARNING_MESSAGE);
                                    }
                                } else {
                                    JOptionPane.showMessageDialog(frame, "Atenção! O agente deve ser selecionado.", "Agente não selecionado!", JOptionPane.WARNING_MESSAGE);
                                }
                            } else {
                                JOptionPane.showMessageDialog(frame, "Atenção! A localidade deve ser selecionada.", "Logradouro não selecionado!", JOptionPane.WARNING_MESSAGE);
                            }
                        } else {
                            JOptionPane.showMessageDialog(frame, "Atenção! O município deve ser definido.", "Município não definido!", JOptionPane.WARNING_MESSAGE);
                        }
                    } else {
                        JOptionPane.showMessageDialog(frame, "Atenção! O coordenador regional deve ser definido.", "Coordenador não preenchido!", JOptionPane.WARNING_MESSAGE);
                    }
                } else {
                    JOptionPane.showMessageDialog(frame, "Atenção! O GRS deve ser preenchido.", "Distrito não preenchido!", JOptionPane.WARNING_MESSAGE);
                }
            } else {
                JOptionPane.showMessageDialog(frame, "Atenção! A data deve ser preenchida.", "Data não preenchida!", JOptionPane.WARNING_MESSAGE);
            }
        }

        return null;
    }

    /**
     * Cadastra o objeto através do frame
     */
    public void cadastrar() {

        //Pergunta ao usuário se ele deseja realizar o cadastro
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja cadastrar o boletim?", "Cadastro de boletim",
                JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Boletimtratamento boletim = this.criaBoletim(opcao);

        //Realiza o cadastro
        if (boletim != null) {
            if (AbstractDAO.cadastrar(boletim)) {
                JOptionPane.showMessageDialog(frame, "Boletim cadastrado com sucesso!", "Cadastro.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();

                //Log do Agente
                int id = AbstractDAO.max(Boletimtratamento.class, "idBoletimTratamento");
                TransacaoDAO.cadastrar("Cadastrou o boletim de tratamento id=" + id + ".");
            }
        }

    }

    /**
     * Altera o objeto através do frame
     */
    public void alterar() {

        //Pergunta ao usuário se ele deseja realizar o cadastro
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja alterar o boletim?", "Alteração de boletim",
                JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Boletimtratamento boletim = this.criaBoletim(opcao);

        //Realiza o cadastro
        if (boletim != null) {
            if (AbstractDAO.alterar(boletim)) {
                //Verifica e exclui as visitas removidas da tabela
                for (int index = 0; index < this.listVisitasRemovidas.size(); index++) {
                    AbstractDAO.excluirPorId("Visitatratamento", "idVisitaTratamento", listVisitasRemovidas.get(index));
                }
                this.listVisitasRemovidas = new ArrayList<Integer>();

                //Log do Agente
                TransacaoDAO.cadastrar("Alterou o boletim de tratamento id=" + boletim.getIdBoletimTratamento() + ".");

                JOptionPane.showMessageDialog(frame, "Boletim alterado com sucesso!", "Alteração.", JOptionPane.INFORMATION_MESSAGE);
                this.limparGUI();
                this.buscar();
            }
        }

    }

    /**
     * Imprime o boletim selecionado
     */
    public boolean imprimir() {

        try {
            InputStream inputStream = getClass().getResourceAsStream("/Boletim_Tratamento.jasper");
            Map parametros = new HashMap();

            //Define os parâmetro do relatório
            if (!frame.textId.getText().isEmpty()) {
                parametros.put("idBoletimtratamento", frame.textId.getText());

                //Executa o relatório
                ReportUtils.openReport("Boletim de Tratamento", inputStream, parametros, ConnectionFactory.getConnection());

            } else {
                JOptionPane.showMessageDialog(frame, "Cadastre o relatório antes de imprimir.\n", "Atenção!", JOptionPane.ERROR_MESSAGE);
            }



            return true;

        } catch (Exception er) {
            JOptionPane.showMessageDialog(frame, "Erro ao criar o relatório.\n" + er, "Erro", JOptionPane.ERROR_MESSAGE);
            er.printStackTrace();
        }

        return false;

    }

    /**
     * Ativa um boletim através do frame
     */
    public void ativar() {

        //Pergunta ao usuário
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja ativar o boletim?",
                "Ativação de boletim!", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Boletimtratamento boletim = this.criaBoletim(opcao);

        //Realiza o cadastro
        if (boletim != null) {
            boletim.setAtivo(true);
            if (AbstractDAO.alterar(boletim)) {
                JOptionPane.showMessageDialog(frame, "Boletim ativado com sucesso!", "Ativação.", JOptionPane.INFORMATION_MESSAGE);
                this.preencheGui(boletim);
                this.buscar();

                //Log do Agente
                TransacaoDAO.cadastrar("Ativou o boletim de tratamento id=" + boletim.getIdBoletimTratamento() + ".");
            }
        }
    }

    /**
     * Desativa um boletim através do frame
     */
    public void desativar() {

        //Pergunta ao usuário
        int opcao = JOptionPane.showOptionDialog(frame, "Tem certeza que deseja desativar o boletim?",
                "Desativação de boletim!", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, frame.botoesOpcoes, frame.botoesOpcoes[0]);

        //Captura o objeto no frame
        Boletimtratamento boletim = this.criaBoletim(opcao);

        //Realiza o cadastro
        if (boletim != null) {
            boletim.setAtivo(false);
            if (AbstractDAO.alterar(boletim)) {
                JOptionPane.showMessageDialog(frame, "Boletim desativado com sucesso!", "Desativação.", JOptionPane.INFORMATION_MESSAGE);
                this.preencheGui(boletim);
                this.buscar();

                //Log do Agente
                TransacaoDAO.cadastrar("Desativou o boletim de tratamento id=" + boletim.getIdBoletimTratamento() + ".");
            }
        }
    }

    /**
     * Realiza a busca de um determinado objeto a partir dos parâmetros
     * definidos no @frame
     */
    public boolean buscar() {

        //Captura os parametros do frame
        String codigoAgente = frame.textBuscaCodigoAgente.getText().trim();
        Date data = Datas.getDate(frame.textBuscaData.getText());
        String codigoLocalidade = frame.textBuscaCodigoLocalidade.getText().trim();
        String codigoMunicipio = frame.textBuscaCodigoMunicipio.getText().trim();

        //Realiza a busca no bd
        List<Boletimtratamento> list = null;

        List<Municipio> listMun = null;
        List<Localidade> listLoc = null;

        if (!frame.textBuscaCodigoMunicipio.getText().isEmpty()) {
            listMun = this.getListMunicipio(codigoMunicipio);
            if (listMun == null) {
                return false;
            }
        }
        if (!frame.textBuscaCodigoLocalidade.getText().isEmpty()) {
            listLoc = this.getListLocalidade(codigoLocalidade, listMun.get(0));
            if (listLoc == null) {
                return false;
            }
        }

        //Incrementa a string para consutar a busca
        String query = "";
        if (!codigoAgente.isEmpty()) {
            List<Agente> listAge = null;
            if (!codigoAgente.equals("-1")) {
                listAge = AbstractDAO.consultar("Agente", "codigo=" + codigoAgente);
            } else {
                listAge = AbstractDAO.consultar("Agente", "codigo=" + codigoAgente + " and nome='" + frame.comboBuscaAgente.getSelectedItem().toString() + "'");
            }
            if (listAge != null) {
                query += " a.idAgente=" + listAge.get(0).getIdAgente();
            } else {
                JOptionPane.showMessageDialog(frame, "Código de agente inexistente ou inativo!", "Atenção!", JOptionPane.WARNING_MESSAGE);
            }
        }
        if (data != null) {
            if (query.length() > 1) {
                query += " AND ";
            }
            query += " b.data='" + data + "'";
        }
        if (listLoc != null) {
            if (query.length() > 1) {
                query += " AND ";
            }
            query += " l.idLocalidade=" + listLoc.get(0).getIdLocalidade();
        }
        if (listMun != null) {
            if (query.length() > 1) {
                query += " AND ";
            }
            query += " m.idMunicipio=" + listMun.get(0).getIdMunicipio();
        }

        if (!query.equals("")) {
            list = AbstractDAO.consultar(
                    "from Boletimtratamento b left join fetch b.agente a left join fetch b.localidade l "
                    + "left join fetch b.municipio m where " + query);
        }

        //Lista os objetos encontrados na tabela
        if (list != null) {
            this.listarPesquisaNaTabela(list);
        } else {
            this.listarPesquisaNaTabela(null);
        }

        return true;
    }

    /**
     * Limpa apenas os componentes de busca e lista a tabela de objetos com
     * todos os objetos do bd
     */
    public void limparBusca() {

        new ApagaElementosDaInterface().apagaJTextField(frame.textBuscaCodigoLocalidade, frame.textBuscaCodigoMunicipio, frame.textBuscaData, frame.textBuscaCodigoAgente,
                frame.textBuscaNomeMunicipio);
        new ApagaElementosDaInterface().apagaJComboBox(frame.comboBuscaLocalidade, frame.comboBuscaAgente);
        EnabledGUIElements.disabledJComponent(frame.textBuscaCodigoLocalidade, frame.comboBuscaLocalidade);
        this.listarPesquisaNaTabela(null);
    }

    /**
     * Abre o frame de visita para ser criada uma nova visita
     */
    public void novaVisita() {

        //Verifica se a localidade do boletim tem ao menos uma quadra e logradouro
        Boletimtratamento boletim = this.criaBoletim(JOptionPane.YES_OPTION);
        if (boletim != null) {

            DefaultTableModel modelo = (DefaultTableModel) frame.tabelaVisitas.getModel();

            //Verifica se a última visita deste boletim já foi registrada
            if (!verificaUltimaVisitaTabela(modelo, 8)) {

                //Verifica se o número máximo de visitas já foi cadastrado
                if (frame.tabelaVisitas.getModel().getRowCount() < Constantes.MAXIMO_VISITAS_POR_BOLETIM) {

                    //Focaliza o novo JInternalFrame
                    IFVisitaTratamento frameAdd = new IFVisitaTratamento(this, boletim, true);
                    FramePrincipal.desktopPanel.add(frameAdd);
                    FramePrincipal.desktopPanel.getDesktopManager().activateFrame(frameAdd);

                } else {
                    JOptionPane.showMessageDialog(frame, "Não podem ser cadastradas mais de "
                            + Constantes.MAXIMO_VISITAS_POR_BOLETIM + " visitas por boletim",
                            "Atenção", JOptionPane.WARNING_MESSAGE);
                }
            } else {
                JOptionPane.showMessageDialog(frame, "Não é possível inserir uma nova visita neste boletim, pois a última visita já foi cadastrada.",
                        "Atenção", JOptionPane.WARNING_MESSAGE);
            }
        }
    }

    /**
     * Remove uma visita na tabela de visitas
     */
    public void removerVisita() {

        //Captura o modelo da tabela
        DefaultTableModel modelo = this.getModelTabelaVisitas();

        //Verifica se existe pelo menos uma linha no modelo
        if (modelo.getRowCount() > 0) {

            //Captura a linha selecionada
            int linha = this.linhaSelecionadaTabelaVisitas();

            //Verifica se a linha capturada existe
            if (linha != -1) {
                int opcao = JOptionPane.showOptionDialog(null, "Você tem certeza que deseja remover a visita selecionada na tabela?", "Remoção de visita",
                        JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                        frame.botoesOpcoes, frame.botoesOpcoes[0]);

                if (opcao == JOptionPane.YES_OPTION) {
                    //Verifica se a visita já está cadastrada no bd
                    if (modelo.getValueAt(linha, 0) != null) {
                        this.listVisitasRemovidas.add(Integer.parseInt(modelo.getValueAt(linha, 0).toString()));

                        //Caso a visita não esteja cadastrada no bd
                    } else {
                        //Percorre todas as linhas e remove qual foi a visita eliminada na GUI de @setVisitas
                        try {
                            Integer codigoQuadra = Integer.parseInt(modelo.getValueAt(linha, 2).toString());
                            Time hora = Horas.getTime(modelo.getValueAt(linha, 1).toString());

                            for (Iterator it = this.setVisitas.iterator(); it.hasNext();) {
                                Visitatratamento visita = (Visitatratamento) it.next();
                                if (visita.getQuadra().getCodigo().equals(codigoQuadra)
                                        && visita.getHora().toString().equals(hora.toString())) {
                                    //Remove a visita de @setVisitas
                                    this.setVisitas.remove(visita);
                                    break;
                                }
                            }

                        } catch (ParseException ex) {
                            ex.printStackTrace();
                        }
                    }
                    modelo.removeRow(linha);
                }
            } else {
                JOptionPane.showMessageDialog(null, "Você não escolheu nenhuma linha da tabela de visitas para ser removida.", "Atenção", JOptionPane.ERROR_MESSAGE);
            }
        }

    }

    /**
     * Edita a visita selecionada
     */
    @Override
    public void editarVisita() {

        boolean boletimAtivo = false;
        if (frame.buttonAlterar.isEnabled() || frame.buttonCadastro.isEnabled()) {
            boletimAtivo = true;
        }

        //Focaliza o novo JInternalFrame
        IFVisitaTratamento frameAdd = new IFVisitaTratamento(this, null, boletimAtivo);
        FramePrincipal.desktopPanel.add(frameAdd);
        FramePrincipal.desktopPanel.getDesktopManager().activateFrame(frameAdd);
        frameAdd.exibirVisita();

    }

    /**
     * Captura o model da tabela de visitas
     *
     * @return
     */
    @Override
    public DefaultTableModel getModelTabelaVisitas() {
        return (DefaultTableModel) frame.tabelaVisitas.getModel();
    }

    /**
     * Captura a linha selecionada na tabela de visitas
     *
     * @return
     */
    @Override
    public Integer linhaSelecionadaTabelaVisitas() {
        return frame.tabelaVisitas.getSelectedRow();
    }
}
